package com.xtyhz.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.xtyhz.mapper.ApUserMapper;
import com.xtyhz.model.req.WxLoginRequest;
import com.xtyhz.model.vo.UserLoginVO;
import com.xtyhz.pojo.app.ApUser;
import com.xtyhz.service.UserService;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户服务实现类
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private WxMaService wxMaService;
    @Autowired
    private ApUserMapper userMapper;

    @Value("${jwt.secret:xtyhz_secret_key}")
    private String jwtSecret;

    @Value("${jwt.expiration:86400}")
    private Long jwtExpiration;

    /**
     * 微信登录
     * @param loginRequest 登录请求
     * @return 登录结果
     */
    @Override
    public UserLoginVO wxLogin(WxLoginRequest loginRequest) {
        try {
            // 调用微信API获取OpenID
            WxMaJscode2SessionResult sessionResult = wxMaService.getUserService().getSessionInfo(loginRequest.getCode());
            String openid = sessionResult.getOpenid();
            
            // 查询用户是否存在
//            User user = getOne(new LambdaQueryWrapper<User>().eq(User::getOpenid, openid));

            ApUser user = userMapper.getUserByOpenId(openid);

            // 用户不存在，创建新用户
            if (user == null) {
                user = new ApUser();
                user.setOpenId(openid);
                //代码解耦
                IsCuoDui(loginRequest, user);

                user.setLanguage("汉语");
                user.setIsActive(1); // 默认正常状态
                user.setCreateTime(new Date());
                user.setUserRole(0);
                user.setUpdatedTime(new Date());
                userMapper.insert(user);
            } else {
                // 用户存在，更新用户信息
                //代码解耦
                IsCuoDui(loginRequest, user);

                user.setUpdatedTime(new Date());
                userMapper.updateById(user);
            }
            
            // 生成JWT令牌
            String token = generateToken(user);
            
            // 封装返回结果
            UserLoginVO loginVO = new UserLoginVO();
            loginVO.setToken(token);
            
            UserLoginVO.UserInfoVO userInfoVO = new UserLoginVO.UserInfoVO();
            BeanUtils.copyProperties(user, userInfoVO);
            loginVO.setUserInfo(userInfoVO);
            
            return loginVO;
            
        } catch (WxErrorException e) {
            log.error("微信登录失败: {}", e.getMessage(), e);
            throw new RuntimeException("微信登录失败: " + e.getMessage());
        }
    }

    /**
     * 代码解耦,登录的参数校验
     * @param loginRequest 请求参数
     * @param user 用户数据
     */
    private void IsCuoDui(WxLoginRequest loginRequest, ApUser user) {
        if (loginRequest.getNickName() != null) {
            user.setNickName(loginRequest.getNickName());
        }

        if (loginRequest.getAvatarUrl() != null) {
            user.setAvatarUrl(loginRequest.getAvatarUrl());
        }
        if (loginRequest.getGender() != null) {
            user.setGender(loginRequest.getGender());
        }
        if (loginRequest.getCountry() != null) {
            user.setCountry(loginRequest.getCountry());
        }
        if (loginRequest.getProvince() != null) {
            user.setProvince(loginRequest.getProvince());
        }
        if (loginRequest.getCity() != null) {
            user.setCity(loginRequest.getCity());
        }
    }

    /**
     * 生成JWT令牌
     * @param user 用户信息
     * @return JWT令牌
     */
    private String generateToken(ApUser user) {
        byte[] secretBytes = Base64.getEncoder().encode(jwtSecret.getBytes());
        Key key = new SecretKeySpec(secretBytes, SignatureAlgorithm.HS256.getJcaName());
        
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user.getId());
        claims.put("openid", user.getOpenId());
        
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(user.getNickName())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + jwtExpiration * 1000))
                .signWith(key)
                .compact();
    }
} 